<!-- 事件日志 -->
<template>
  <div class="dashboard-editor-container">
    <div style="display:flex;justify-content:space-between;">
      <partitionTree :nodeData="nodeData" :expandArray="expandArray" :addTemplate="false" :defaultExpandAll="false" dialogName="OpenPorts"
        @handleNodeClick="handleNodeClick" ref="partitionTree" @toggleVisibility="toggleVisibility">
      </partitionTree>
      <div :style="{ width: containerWidth }" class="box"
        style="background:#fff;border: 1px solid #ddd;border-radius: 4px;box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);">
        <el-row style="background: #fff; padding: 16px 16px 0;">
          <connsearch ref="connsearch" :formOptions="formOptions" @search="search" @reset="reset"></connsearch>
          <div class="tabclick">
            <div class="tabitem" @click="handleClick()">
              <span><i :class="tab ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i></span>
            </div>
          </div>
          <el-row>
            <el-tabs type="border-card" v-if="tab" style="margin-top:16px;" @tab-click="tabClick">
              <el-tab-pane label="资产名称统计" lazy>
                <el-col :xs="24" :sm="24" :lg="24">
                  <piechart :chartData="pie2Data" @pieclick="echartsClick" title="资产名称统计" />
                </el-col>
              </el-tab-pane>
              <el-tab-pane label="端口号统计" lazy>
                <el-col :xs="24" :sm="24" :lg="24">
                  <piechart :chartData="pie3Data" @pieclick="echartsClick" title="端口号统计" />
                </el-col>
              </el-tab-pane>
            </el-tabs>
          </el-row>
          <el-col :xs="{ span: 24 }" :sm="{ span: 24 }" :md="{ span: 24 }" :lg="{ span: 24 }" :xl="{ span: 24 }"
            style="padding-right: 8px;margin:16px 0;">
            <el-tabs type="border-card" v-model="tabTitle2" @tab-click="tabClick2">
              <el-tab-pane key="端口信息" label="端口信息" name="端口信息" lazy>
                <el-table stripe border :data="tableData" style="width: 100%; margin-top: 15px">
                  <el-table-column label="序号" width="60" type="index"
                    :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
                  <el-table-column label="协议类型" show-overflow-tooltip prop="TransProtocol" width="120"></el-table-column>
                  <el-table-column label="开放端口" show-overflow-tooltip prop="Port" width="120"></el-table-column>
                  <el-table-column label="端口解释" show-overflow-tooltip prop="PortDesc"></el-table-column>
                  <el-table-column label="安全级别" show-overflow-tooltip prop="Level" width="120"></el-table-column>
                  <el-table-column label="应用层协议" show-overflow-tooltip prop="AppProtocol" width="220"></el-table-column>
                  <el-table-column label="资产数量" show-overflow-tooltip prop="DeviceCount" width="120"></el-table-column>
                  <el-table-column label="操作" width="120px" fixed="right">
                    <template slot-scope="scope">
                      <el-button size="mini" type="success" @click="detailsChange(scope.row)">涉及资产</el-button>
                      <!-- <el-button size="mini" type="primary" @click="JoinPort(scope.row)">加入常用端口</el-button> -->
                    </template>
                  </el-table-column>
                </el-table>
                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page=pageNum
                  :page-size=pageSize background layout="total, prev, pager, sizes, next, jumper" :total="total">
                </el-pagination>
              </el-tab-pane>
              <el-tab-pane key="开放明细" label="开放明细" name="开放明细" lazy>
                <el-table stripe border :data="tableData2" style="width: 100%; margin-top: 15px">
                  <el-table-column label="序号" width="60" type="index"
                    :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
                  <el-table-column label="部门" show-overflow-tooltip prop="Department" width="120px"></el-table-column>
                  <el-table-column label="资产名称" show-overflow-tooltip prop="DeviceName" width="160px"></el-table-column>
                  <el-table-column label="使用者" show-overflow-tooltip prop="UserName" width="120px"></el-table-column>
                  <el-table-column label="协议类型" show-overflow-tooltip prop="TransProtocol" width="120px"></el-table-column>
                  <el-table-column label="开放端口" show-overflow-tooltip prop="Port" width="120px"></el-table-column>
                  <el-table-column label="端口解释" show-overflow-tooltip prop="PortDesc"></el-table-column>
                  <el-table-column label="进程信息" show-overflow-tooltip prop="ProcPath"></el-table-column>
                </el-table>
                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page=pageNum
                  :page-size=pageSize background layout="total, prev, pager, sizes, next, jumper" :total="total">
                </el-pagination>
              </el-tab-pane>
            </el-tabs>
            <el-dialog :close-on-click-modal="false" :close-on-press-escape=false title="加入常用端口"
              :visible.sync="moderVisible" v-el-drag-dialog width="800px">
              <el-form label-width="140px" :model="Moder" ref="Moder">
                <el-row class="ruleMain">
                  <el-divider content-position="left">基本规则内容</el-divider>
                  <el-form-item label='端口号：' prop="Port">
                    <el-input v-model.number="Moder.Port" placeholder="请输入端口号" maxlength="64" disabled></el-input>
                  </el-form-item>
                  <el-form-item label='端口协议类型：' prop="ProtoType">
                    <el-radio v-model="Moder.ProtoType" :label="1">通用协议</el-radio>
                    <el-radio v-model="Moder.ProtoType" :label="2">工业协议</el-radio>
                  </el-form-item>
                  <el-form-item label='传输层协议：' prop="TransProtocol">
                    <el-radio v-model="Moder.TransProtocol" label="TCP">TCP</el-radio>
                    <el-radio v-model="Moder.TransProtocol" label="UDP">UDP</el-radio>
                  </el-form-item>
                  <el-form-item label='端口解释：' prop="PortDesc">
                    <el-input v-model="Moder.PortDesc" placeholder="请输入端口解释，例：http" maxlength="32"></el-input>
                  </el-form-item>
                  <el-form-item label='端口详细描述：' prop="DetailDesc">
                    <el-input v-model="Moder.DetailDesc" placeholder="请输入详细描述" maxlength="64"></el-input>
                  </el-form-item>
                </el-row>
              </el-form>
              <el-divider></el-divider>
              <span slot="footer" class="dialog-footer">
                <el-button type="primary" @click="submit()">确 定</el-button>
                <el-button type="info" @click="moderVisible = false">取 消</el-button>
              </span>
            </el-dialog>
          </el-col>
        </el-row>
      </div>
    </div>
  </div>
</template>

<script>
import Cookies from 'js-cookie'
import connsearch from "@/components/connSearch";
import eventTrends from './components/BarChart3.vue'  //柱状图
import piechart from "./components/piechart.vue";
import { parseTime, GetDeviceTree2} from "@/utils/index.js";
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
import { connrequest } from "@/api/firstPage.js"
import partitionTree from "@/components/partitionTree";

export default {
  directives: { elDragDialog },
  components: { connsearch, eventTrends, piechart, partitionTree },
  data() {
    let that = this
    return {
      activeName: "",
      tabTitle: '资产名称统计',
      tabTitle2: "端口信息",
      pageNum: 1,
      pageSize: 10,
      total: 0,
      tab: false,
      barchartData: { xAxis: [], series: [] },
      pie1Data: [],
      pie2Data: [],
      pie3Data: [],
      nodeData: [],
      expandArray: [],
      containerWidth: 'calc(100% - 275px)',
      tableData: [],
      tableData2: [],
      devices: [],
      searchform: {},
      options: {},
      nodeobj: {},
      searchobj: {},
      echartsobj: {},
      detailsobj: {},
      resourceForm: {},
      DeviceObj: {},
      moderVisible: false,
      Moder: {},
      formOptions: [
        {
          col: 8,
          label: "端口号",
          prop: "Port",
          element: "el-input",
          placeholder: "请输入端口号",
          maxlength: 5,
          regular: "[^0-9]", // 表示替换掉非数字字符
          events: {
            input(val) {
              that.searchform.Port = val
            },
          },
        },
      ],
    };
  },
  //生命周期 - 创建完成（访问当前this实例）
  created() {
    this.pageSize = (Cookies.get('Zhuoguan_DefaultPageLength') || 10) * 1;

    let endTime = new Date(new Date().setHours(0, 0, 0, 0)).getTime()
    let startTime = endTime - ((Cookies.get('Zhuoguan_DefaultLogDays') || 7) * 24 * 3600 * 1000);
    let arr = [parseTime(startTime), '']
    this.formOptions.map(item => {
      if (item.label === '日期') {
        item.initValue = arr
      }
    })
    this.$set(this.searchform, 'timeRange', arr)
    this.getData()
  },
  //生命周期 - 挂载完成（访问DOM元素）
  mounted() {
    this.initData()
  },
  methods: {
    parseTime,
    async initData(searchobj = {}) {
      try {
        const { DeviceTree, devices } = await GetDeviceTree2('OpenPorts', searchobj)
        this.nodeData = DeviceTree
        this.devices = devices
        this.expandArray = [DeviceTree?.[0]?.Name]
      } catch (error) {
        this.$message.error('加载设备树数据失败');
      }
    },
    handleNodeClick(nodeData) {
      this.pageNum = 1
      this.nodeobj = { DepartmentID: nodeData.data.isDevice ? nodeData.data.DepartmentID : nodeData.data.ID, DeviceUUID: nodeData.data.isDevice ? nodeData.data.DeviceUUID : '' }
      this.echartsobj = {}
      this.detailsobj = {}
      this.getData({ ...this.searchobj, ...this.nodeobj })
    },
    toggleVisibility(isHidden) {
      if (isHidden)
        this.containerWidth = '100%';
      else
        this.containerWidth = 'calc(100% - 275px)';
    },
    async detailsChange(row) {
      this.pageNum = 1
      this.pageSize = 10
      this.tabTitle2 = '开放明细'
      this.detailsobj = { ...this.searchobj, DeviceUUID: '', ...this.echartsobj,  Port: row.Port, ...this.nodeobj }
      this.GetOpenPortDetail(this.detailsobj)
      switch (this.tabTitle) {
        case '日期统计趋势':
          this.GetProcessLoadSumByDate(this.detailsobj)
          break;
        case '资产名称统计':
          this.GetPortStatisticByDevice(this.detailsobj)
          break;
        default:
          this.GetPortStatisticByPortNum(this.detailsobj)
          break;
      }
    },
    JoinPort(row) {
      this.Moder = { ...row, ProtoType: 1 }
      this.moderVisible = true
    },
    async submit(Moder, Action) {
      const data = {
        Data: {
          ...this.Moder
        }
      }
      const res = await connrequest('AddCommonPort', data)
      if (res.Status.StatusCode === 0) {
        this.$message.success('加入常用端口成功成功')
        this.moderVisible = false
        this.getData()
      }
    },
    // 获取所有数据
    getData(searchobj = {}) {
      switch (this.tabTitle2) {
        case '端口信息':
          this.GetEventLog(searchobj)
          break;
        case '开放明细':
          this.GetOpenPortDetail(searchobj)
          break;
      }
      switch (this.tabTitle) {
        case '日期统计趋势':
          this.GetProcessLoadSumByDate(searchobj)
          break;
        case '资产名称统计':
          this.GetPortStatisticByDevice(searchobj)
          break;
        default:
          this.GetPortStatisticByPortNum(searchobj)
          break;
      }
    },
    echartsClick(val, title) {
      this.pageNum = 1
      if (title === '资产名称统计') {
        this.echartsobj = { DeviceUUID: this.devices.find(item => item.DeviceName === val)?.DeviceUUID }
        switch (this.tabTitle2) {
          case '端口信息':
            this.GetEventLog({ ...this.searchobj, ...this.nodeobj, ...this.echartsobj })
            break;
          case '开放明细':
            this.GetOpenPortDetail({ ...this.searchobj, ...this.nodeobj, ...this.echartsobj, ...this.detailsobj })
            break;
        }
      } else {
        this.echartsobj = { Port: val.replace(/\D/g, '') * 1 }
        switch (this.tabTitle2) {
          case '端口信息':
            this.GetEventLog({ ...this.searchobj, ...this.nodeobj, ...this.echartsobj })
            break;
          case '开放明细':
            this.GetOpenPortDetail({ ...this.searchobj, ...this.nodeobj, ...this.echartsobj, ...this.detailsobj })
            break;
        }
      }
      // this.GetEventLog()
    },
    tabClick(row) {
      this.tabTitle = row.label
      switch (row.label) {
        case '日期统计趋势':
          this.GetProcessLoadSumByDate({ ...this.searchobj, ...this.nodeobj, ...this.detailsobj })
          break;
        case '资产名称统计':
          this.GetPortStatisticByDevice({ ...this.searchobj, ...this.nodeobj, ...this.detailsobj })
          break;
        default:
          this.GetPortStatisticByPortNum({ ...this.searchobj, ...this.nodeobj, ...this.detailsobj })
          break;
      }
    },
    tabClick2(row) {
      this.pageNum = 1
      this.pageSize = 10
      this.tabTitle2 = row.label
      switch (row.label) {
        case '端口信息':
          this.GetEventLog({ ...this.searchobj, ...this.echartsobj, ...this.nodeobj })
          break;
        case '开放明细':
          this.GetOpenPortDetail({ ...this.searchobj, ...this.echartsobj, ...this.nodeobj })
          break;
      }
    },
    // 获取事件日志列表
    async GetEventLog(searchobj = {}) {
      const data = {
        Paging: {
          QueryPageNo: this.pageNum,
          QueryPageLength: this.pageSize
        },
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          DeviceUUID: this.searchform.DeviceUUID,
          ProcName: this.searchform.ProcName,
          Port: this.searchform.Port * 1,
          ...searchobj
        }
      }
      const res = await connrequest('GetOpenPortGroupByPortNum', data)
      res.Data = res.Data || []
      this.tableData = res.Data
      this.total = res.Paging.TotalCount || 0
    },
    async GetOpenPortDetail(searchobj = {}) {
      const data = {
        Paging: {
          QueryPageNo: this.pageNum,
          QueryPageLength: this.pageSize
        },
        Filter: {
          StartTime: searchobj?.timeRange?.[0] || '',
          EndTime: searchobj?.timeRange?.[1] || '',
          DeviceUUID: searchobj?.DeviceUUID,
          Port: searchobj?.Port * 1,
          ...searchobj
        }
      }
      const res = await connrequest('GetOpenPortDetail', data)
      this.total = res.Paging.TotalCount || 0
      this.tableData2 = res.Data
    },
    // 资产名称统计
    async GetPortStatisticByDevice(searchobj = {}) {
      let arr = []
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          DeviceUUID: this.searchform.DeviceUUID,
          ProcName: this.searchform.ProcName,
          Port: this.searchform.Port * 1,
          ...searchobj
        }
      }
      const res = await connrequest('GetPortStatisticByDevice', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        arr.push({ name: item.DeviceName || '未知名称', value: item.PortCount })
      })
      this.pie2Data = arr
    },
    // 端口号统计
    async GetPortStatisticByPortNum(searchobj = {}) {
      let arr = []
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          ...searchobj
        }
      }
      const res = await connrequest('GetPortStatisticByPortNum', data)
      res.Data.map(item => {
        arr.push({ name: `${item.Port}(${item.AppProtocol || '-'})` || '未知', value: item.PortCount || 0 })
      })
      this.pie3Data = arr.sort((a, b) => b.value - a.value).slice(0, 10);
    },
    // 搜索
    search(val) {
      this.pageNum = 1
      this.searchobj = { ...val, Port: val.Port * 1 }
      this.searchform = { ...val, Port: val.Port * 1 }
      this.getData({ ...this.echartsobj, ...this.searchobj, ...this.nodeobj })
      this.initData({...this.searchobj})
    },
    // 重置
    reset() {
      this.pageNum = 1
      this.formOptions = this.formOptions.map(item => {
        item.initValue = ""
        return item
      })
      this.searchform = {}
      this.echartsobj = {}
      this.searchobj = {}
      this.detailsobj = {}
      this.nodeobj = {}
      this.$set(this.searchform, 'Port', '')
      this.$refs.connsearch.addInitValue()
      this.getData()
      this.initData()
    },
    handleSizeChange(pageSize) {
      this.pageSize = pageSize
      this.pageNum = 1
      switch (this.tabTitle2) {
        case '端口信息':
          this.GetEventLog({ ...this.searchobj, ...this.echartsobj, ...this.nodeobj })
          break;
        case '开放明细':
          this.GetOpenPortDetail({ ...this.searchobj, ...this.echartsobj, ...this.nodeobj, ...this.detailsobj })
          break;
      }
    },
    handleCurrentChange(pageNum) {
      this.pageNum = pageNum
      switch (this.tabTitle2) {
        case '端口信息':
          this.GetEventLog({ ...this.searchobj, ...this.echartsobj, ...this.nodeobj })
          break;
        case '开放明细':
          this.GetOpenPortDetail({ ...this.searchobj, ...this.echartsobj, ...this.nodeobj, ...this.detailsobj })
          break;
      }
    },
    handleClick() {
      this.tab = !this.tab
    }
  },
};
</script>
<style lang="scss" scoped>
@import "./components/css/conncss.scss";
</style>